using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Configuration;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.IO;
using OSGeo.MapServer;
using Gaiocorp.SLViewer.ImageMapServer;

namespace UI
{
	/// <summary>
	/// XML controller for FlashViewer (could be written in each environment is supported XML and the map server
	/// </summary>
	public partial class xml : System.Web.UI.Page
	{
        Gaiocorp.SLViewer.ImageMapServer.MapServer slmap = null;
        XmlDocument xmlRequest = new XmlDocument();
        string sExternalURL = string.Empty;
        bool legCreated;
        
        /// <summary>
    /// Get xml request and send xml response
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
        protected void Page_Load(object sender, System.EventArgs e)
        {
            string strMapHeight = string.Empty;
            string strMapWidth = string.Empty;
            int xmin = -1;
            int xmax = -1;
            int ymin = -1;
            int ymax = -1;
            XmlElement xmlLegend = null;
            resultCacheObj results = null;
            XmlElement xmlResults = null;
            XmlDocument xmlResponse = new XmlDocument();

            //SLViewer.ImageMapServer.Configuration  conf = (SLViewer.ImageMapServer.Configuration)Session["CONFIGURATION"];
            try
            {

                //Set the size of the map
                if (Session["MAPWIDTH"] == null || Session["MAPHEIGHT"] == null)
                {
                    //IDictionary generaldictionary = (IDictionary)ConfigurationSettings.GetConfig("General");
                    //strMapHeight = generaldictionary["mapHeight"].ToString();
                    //strMapWidth = generaldictionary["mapWidth"].ToString();
                    strMapWidth = System.Configuration.ConfigurationManager.AppSettings["mapwidth"];
                    strMapHeight = System.Configuration.ConfigurationManager.AppSettings["mapheight"];
                    Session["MAPWIDTH"] = strMapWidth;
                    Session["MAPHEIGHT"] = strMapHeight;
                }
                else
                {
                    strMapWidth = Session["MAPWIDTH"].ToString();
                    strMapHeight = Session["MAPHEIGHT"].ToString();
                }
                //Change size params in the conf object
                //conf.GeneralConfig.MapHeight = Convert.ToInt32(strMapHeight.ToString());
                //conf.GeneralConfig.MapWidth = Convert.ToInt32(strMapWidth.ToString());

                //first Map
                //read generic map if exists, otherwise create a new one from map file
                slmap = (MapServer)Session["MAP"];
                //mapObj UMNmap=(mapObj)Session["MAPOBJECT"];
                if (slmap == null)
                {
                    //map = MapServerFactory.GetFactory(conf);
                    slmap = new MapServer(Session["mapfile"].ToString(), Convert.ToInt32(Session["MAPWIDTH"]), Convert.ToInt32(Session["MAPHEIGHT"]));
                    //UMNmap = new mapObj(Session["mapfile"].ToString());
                }

                //Set MapSize
                slmap.SetMapSize(Convert.ToInt32(strMapWidth), Convert.ToInt32(strMapHeight));
                //read the request

                Request.ContentType = "text/XML";
                xmlRequest.Load(Request.InputStream);
                //System.Diagnostics.Debug.WriteLine(xmlRequest.OuterXml);
                String Action = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["action"].Value;
                try
                {
                    String doReset = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["reset"].Value;
                    Session["LEGEND_CREATED"] = null;
                }
                catch { }
                //GIS Action to do
                switch (Action.ToUpper())
                {
                    case "INITMAP":
                        //get init map 
                        slmap.DoPan((double)0, (double)0, (double)0, (double)0);
                        break;
                    case "FULLEXTENT":
                        //full extent
                        slmap.DoZoomFullExtent();
                        break;
                    case "ZOOMLAST":
                        //torno previous
                        slmap.DoZoomPreviousExtent();
                        break;
                    case "ZOOMIN":
                        //zoomin
                        slmap.DoZoom(ZOOMMODE.ZoomIn);
                        break;
                    case "ZOOMOUT":
                        //zoomout
                        slmap.DoZoom(ZOOMMODE.ZoomOut);
                        break;
                    case "REMOVEPIN":
                        slmap.RemovePoint((string)Session["mapfile"]);
                        break;
                    case "SETLEGEND":
                        SetLegend();
                        break;
                    case "SETSCALE":
                        string sScale = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["scale"].Value.ToString();
                        slmap.SetScale(Convert.ToDouble(sScale));
                        break;
                    case "PRINT":
                        string sPScale = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["pscale"].Value.ToString();
                        string sPSize = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["psize"].Value.ToString();
                        string[] sPrintResult = slmap.PrintMap(sPScale, sPSize);
                        Session["PRINTIMAGE"] = sPrintResult[0];
                        Session["PRINTLEGIMAGE"] = sPrintResult[1];
                        Session["PRINTSCALE"] = sPrintResult[2];
                        break;
                    case "CLEAR":
                        break;
                    case "ZOOMINBOX":
                    case "ZOOMOUTBOX":
                    case "SELECT":
                    case "GETXYBUTTON":
                    case "INFO":
                    case "HYPERLINK":
                    case "GETLEGEND":
                    case "PAN":
                    case "ATTRIBUTEQUERY":
                    case "IDQUERY":
                    case "GETATTRTABLE":
                    case "ADDSHPPNT":
                        try
                        {
                            System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CurrentCulture;
                            String sXmin = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["xmin"].Value.Replace(".", ",");
                            String sXmax = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["xmax"].Value.Replace(".", ",");
                            String sYmin = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["ymin"].Value.Replace(".", ",");
                            String sYmax = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["ymax"].Value.Replace(".", ",");
                            double dxmin = double.Parse(sXmin);
                            double dymin = double.Parse(sYmin);
                            double dxmax = double.Parse(sXmax);
                            double dymax = double.Parse(sYmax);
                            xmin = (int)dxmin;
                            xmax = (int)dxmax;
                            ymin = (int)dymin;
                            ymax = (int)dymax;
                        }
                        catch { }
                        if (Action.ToUpper() == "ZOOMINBOX")
                        {
                            slmap.DoZoomBox(ZOOMMODE.ZoomIn, xmin, ymin, xmax, ymax);
                        }
                        if (Action.ToUpper() == "ZOOMOUTBOX")
                        {
                            slmap.DoZoomBox(ZOOMMODE.ZoomOut, xmin, ymin, xmax, ymax);
                        }
                        if (Action.ToUpper() == "PAN")
                        {
                            slmap.DoPan(xmin, ymin, xmax, ymax);
                        }
                        //**********
                        if (Action.ToUpper() == "SELECT")
                        {
                            if (Session["ACTIVELAYER_IDX"] != null && Session["ACTIVELAYER_IDX"].ToString() != "-1")
                            {
                                int intActiveLayerID = (int)Session["ACTIVELAYER_IDX"];
                                xmlResults = slmap.DoSelectBox(intActiveLayerID, xmin, ymin, xmax, ymax);
                                Session["QueryResults"] = results;
                            }
                        }
                        //**********
                        if (Action.ToUpper() == "GETXYBUTTON")
                        {
                            slmap.RemovePoint((string)Session["mapfile"]);
                            int[] xy = slmap.GetXYCoordinates(xmin, ymin);
                            Session["XY_RESULT_X"] = xmin;
                            Session["XY_RESULT_Y"] = ymin;
                            Session["XY_RESULT_X_REALEXT"] = xy[0];
                            Session["XY_RESULT_Y_REALEXT"] = xy[1];
                        }
                        //**********
                        if (Action.ToUpper() == "GETLEGEND")
                        {
                            if (Session["LEGEND_CREATED"] == null)
                                legCreated = false;
                            else
                                legCreated = true;
                            if (Session["ACTIVELAYER_IDX"] == null)
                                xmlLegend = slmap.GetLegend(-1, legCreated);
                            else
                                xmlLegend = slmap.GetLegend(Convert.ToInt32(Session["ACTIVELAYER_IDX"].ToString()), legCreated);
                            Session["LEGEND_CREATED"] = true;
                        }

                        if (Action.ToUpper() == "INFO")
                        {
                            if (Session["ACTIVELAYER_IDX"] != null && Session["ACTIVELAYER_IDX"].ToString() != "-1")
                            {
                                int intActiveLayerID = (int)Session["ACTIVELAYER_IDX"];
                                xmlResults = slmap.DoIdentify(intActiveLayerID, xmin, ymin);
                                Session["QueryResults"] = results;
                                
                            }
                        }
                        if (Action.ToUpper() == "GETATTRTABLE")
                        {
                            string sLyrName = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["layer"].Value.ToString();
                            xmlResults = slmap.GetAttributeTableAsXML(sLyrName);
                        }
                        //HYPERLINK button
                        if (Action.ToUpper() == "HYPERLINK")
                        {
                            string sLayer = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["layer"].Value;
                            string sHLinkField = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["linkfield"].Value;
                            string sHLinkParams = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["linkParams"].Value;
                            sExternalURL = slmap.getURL(xmin, ymin, sLayer, sHLinkField, sHLinkParams);
                        }
                        if (Action.ToUpper() == "ATTRIBUTEQUERY")
                        {
                            string sLayer = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["layer"].Value;
                            string sWhere = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["where"].Value;
                            slmap.DoQueryByAttributes(sLayer, sWhere);
                        }
                        if (Action.ToUpper() == "IDQUERY")
                        {
                            string sLayer = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["layer"].Value;
                            string sShpID = xmlRequest.GetElementsByTagName("REQUEST").Item(0).Attributes["shpid"].Value;
                            slmap.DoSelectByIndex(sLayer, Convert.ToInt32(sShpID));
                        }
                        if (Action.ToUpper() == "ADDSHPPNT")
                        {
                            if (Session["ACTIVELAYER_IDX"] != null && Session["ACTIVELAYER_IDX"].ToString() != "-1")
                            {
                                int intActiveLayerID = (int)Session["ACTIVELAYER_IDX"];
                                xmlResults = slmap.NewRecAsXML(intActiveLayerID, xmin, ymin);
                                //map.AddPointToLayer(xmin, ymin, intActiveLayerID);
                            }
                        }
                        break;
                }
                //xml response
                //XmlDocument xmlResponse = new XmlDocument();
                XmlElement elmResponse = xmlResponse.CreateElement("RESPONSE");
                if (Session["LEGEND_CREATED"] == null)
                {
                    legCreated = false;
                }
                else
                {
                    legCreated = true;
                }

                // Get Legend First. This will also return the mapobject with
                // 
                if (Session["ACTIVELAYER_IDX"] == null)
                {

                    xmlLegend = slmap.GetLegend(-1, legCreated);
                }
                else
                {
                    xmlLegend = slmap.GetLegend(Convert.ToInt32(Session["ACTIVELAYER_IDX"].ToString()), legCreated);
                }
                // Set the session variable so we dont re-create the legend images
                Session["LEGEND_CREATED"] = true;

                if (xmlLegend != null)
                {
                    XmlDocumentFragment docFragment = xmlResponse.CreateDocumentFragment();
                    docFragment.InnerXml = xmlLegend.OuterXml.ToString();
                    XmlNode n = docFragment;
                    elmResponse.AppendChild(n);
                }

                if (Action.ToUpper() != "INFO" && Action.ToUpper() != "GETATTRTABLE" && Action.ToUpper() != "HYPERLINK" && Action.ToUpper() != "PRINT")
                {
                    XmlElement elmImage = xmlResponse.CreateElement("IMAGE");
                    string[] Mapsize = slmap.GetMapSize();
                    elmImage.SetAttribute("width", Mapsize[0]);
                    elmImage.SetAttribute("height", Mapsize[1]);
                    elmImage.SetAttribute("scale", string.Format("{0:0.00}", slmap.GetScale()));
                    string[] curExtent = slmap.GetCurrentMapExtent();
                    elmImage.SetAttribute("minx", curExtent[0]);
                    elmImage.SetAttribute("miny", curExtent[1]);
                    elmImage.SetAttribute("maxx", curExtent[2]);
                    elmImage.SetAttribute("maxy", curExtent[3]);
                    XmlElement elmExtent = xmlResponse.CreateElement("FULLEXTENT");
                    elmExtent.SetAttribute("minx", System.Configuration.ConfigurationManager.AppSettings["InitXMin"].ToString());
                    elmExtent.SetAttribute("miny", System.Configuration.ConfigurationManager.AppSettings["InitYMin"].ToString());
                    elmExtent.SetAttribute("maxx", System.Configuration.ConfigurationManager.AppSettings["InitXMax"].ToString());
                    elmExtent.SetAttribute("maxy", System.Configuration.ConfigurationManager.AppSettings["InitYMax"].ToString());

                    string imgUrl = string.Empty;

                    if (Action.ToUpper() == "SELECT" || Action.ToUpper() == "IDQUERY" || Action.ToUpper() == "ATTRIBUTEQUERY")
                    {
                        imgUrl = slmap.GetURLMapSelection();
                        elmImage.SetAttribute("imageURL", imgUrl);
                        if (Action.ToUpper() == "SELECT")
                        {
                            elmImage.SetAttribute("selectionmap", "yes");
                        }
                        else elmImage.SetAttribute("selectionmap", "no");
                    }
                    else
                    {
                        imgUrl = slmap.GetURLMap();
                        elmImage.SetAttribute("imageURL", imgUrl);
                        elmImage.SetAttribute("selectionmap", "no");
                    }
                    if (imgUrl != null)
                    {
                        elmResponse.AppendChild((XmlNode)elmImage);
                    }
                    elmResponse.AppendChild((XmlNode)elmExtent);
                }


                if (xmlResults != null)
                {
                    XmlDocumentFragment docFragment = xmlResponse.CreateDocumentFragment();
                    docFragment.InnerXml = xmlResults.OuterXml.ToString();
                    XmlNode n = docFragment;
                    elmResponse.AppendChild(n);
                }

                if (sExternalURL != string.Empty)
                {
                    XmlElement elmXURL = xmlResponse.CreateElement("EXTERNALURL");
                    elmXURL.InnerText = sExternalURL;
                    elmResponse.AppendChild((XmlNode)elmXURL);
                }

                if (Action.ToUpper() == "PRINT")
                {
                    XmlElement elmXURL = xmlResponse.CreateElement("PRINTIMAGE");
                    elmXURL.InnerText = "YES";
                    elmResponse.AppendChild((XmlNode)elmXURL);
                }

                xmlResponse.AppendChild((XmlNode)elmResponse);
                Session["MAP"] = slmap;
            }
            catch (Exception ex)
            {
                //xml response
               
                XmlElement elmResponse = xmlResponse.CreateElement("RESPONSE");
                XmlElement elmError = xmlResponse.CreateElement("ERROR");
                string sError = ex.Message.ToString();
                sError = sError.Replace("\n", " ");
                sError = sError.Replace("\r", " ");
                sError = sError.Replace("\t", " ");
                elmError.InnerText = sError;
                elmResponse.AppendChild((XmlNode)elmError);
                xmlResponse.AppendChild((XmlNode)elmResponse);

            }
            Response.Clear();
            Response.ContentType = "text/XML";
            Response.Write("<?xml version='1.0' ?>");
            Response.Write(xmlResponse.InnerXml);
        }

    protected void SetLegend()
    {
        XmlReaderSettings settings = new XmlReaderSettings();
        XmlReader reader = XmlReader.Create(new StringReader(xmlRequest.OuterXml));
        reader.MoveToContent();
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element && reader.Name == "LAYER")
            {                
                slmap.SetLayerStatus(reader.GetAttribute("name").ToString(), Convert.ToInt32(reader.GetAttribute("visible").ToString()));
            }
            if (reader.NodeType == XmlNodeType.Element && reader.Name == "ACTIVE_INDEX")
            {
                string sActiveIdx = reader.ReadInnerXml();
                Session["ACTIVELAYER_IDX"] = Convert.ToInt32(sActiveIdx);
                    //reader.ReadContentAsString();               
            }
            if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "RESPONSE")
            {
                break;
            }

        }

        reader.Close();
    }

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    

		}
		#endregion
	}
}
